package com.tool.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SecurityUtils {

	private static final Logger LOGGER = LoggerFactory.getLogger(SecurityUtils.class);
	/***
	 * yyyy-MM-dd HH:mm:ss
	 */
	private static final String yyyyMMddHHmmss = "yyyy-MM-dd";

	/** 秒 */
	private static final Long TIME_OFFSET = 1000L * 100;

	private static boolean isMatch(String regex, String orginal) {
		if (orginal == null || orginal.trim().equals("")) {
			return false;
		}
		Pattern pattern = Pattern.compile(regex);
		Matcher isNum = pattern.matcher(orginal);
		return isNum.matches();
	}

	public static boolean isPositiveInteger(String orginal) {
		return isMatch("^\\+{0,1}[1-9]\\d*", orginal);
	}

	public static boolean isNegativeInteger(String orginal) {
		return isMatch("^-[1-9]\\d*", orginal);
	}

	public static boolean isWholeNumber(String orginal) {
		return isMatch("[+-]{0,1}0", orginal) || isPositiveInteger(orginal) || isNegativeInteger(orginal);
	}

	public static boolean isPositiveDecimal(String orginal) {
		return isMatch("\\+{0,1}[0]\\.[1-9]*|\\+{0,1}[1-9]\\d*\\.\\d*", orginal);
	}

	public static boolean isNegativeDecimal(String orginal) {
		return isMatch("^-[0]\\.[1-9]*|^-[1-9]\\d*\\.\\d*", orginal);
	}

	public static boolean isDecimal(String orginal) {
		return isMatch("[-+]{0,1}\\d+\\.\\d*|[-+]{0,1}\\d*\\.\\d+", orginal);
	}

	public static boolean isRealNumber(String orginal) {
		return isWholeNumber(orginal) || isDecimal(orginal);
	}

	/***
	 * 两个日期相差多少秒
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int getTimeDelta(Date date1, Date date2) {
		long timeDelta = (date1.getTime() - date2.getTime()) / 1000;// 单位是秒
		int secondsDelta = timeDelta > 0 ? (int) timeDelta : (int) timeDelta;
		return secondsDelta;
	}

	/***
	 * 两个日期相差多少秒 dateStr1 - dateStr2
	 * 
	 * @param dateStr1 :yyyy-MM-dd HH:mm:ss
	 * @param dateStr2 :yyyy-MM-dd HH:mm:ss
	 */
	public static int getTimeDelta(String dateStr1, String dateStr2) {
		Date date1 = parseDateByPattern(dateStr1, yyyyMMddHHmmss);
		Date date2 = parseDateByPattern(dateStr2, yyyyMMddHHmmss);
		return getTimeDelta(date1, date2);
	}

	/***
	 * 两个日期相差多少秒 dateStr1 - dateStr2
	 * 
	 * @param dateStr1 :yyyy-MM-dd HH:mm:ss
	 * @param dateStr2 :yyyy-MM-dd HH:mm:ss
	 */
	public static int getCurrentTimeDelta(String dateStr1) {
		Date date1 = parseDateByPattern(dateStr1, yyyyMMddHHmmss);
		Date date2 = new Date();
		return getTimeDelta(date1, date2);
	}

	public static Date parseDateByPattern(String dateStr, String dateFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		try {
			return sdf.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * string -> int
	 * 
	 * @param str
	 * @return
	 */
	public static int ConvertInt(String str) {
		return Integer.valueOf(str);
	}

	/**
	 * string -> long
	 * 
	 * @param str
	 * @return
	 */
	public static Long ConvertLong(String str) {
		return Long.valueOf(str);
	}

	/**
	 * string -> Date
	 * 
	 * @param str
	 * @return
	 */
	public static Date ConvertDate(String str) {
		return new Date(ConvertLong(str));
	}

	/**
	 * 获取UUID,用于设置上传文件名
	 * 
	 * @return
	 */
	public static String getUUID() {
		UUID uid = UUID.randomUUID();
		String id = uid.toString();
		return id.replaceAll("-", "");
	}

	public static String getOrderIdByUUId() {
		int machineId = 1;// 最大支持1-9个集群机器部署
		int hashCodeV = UUID.randomUUID().toString().hashCode();
		if (hashCodeV < 0) {// 有可能是负数
			hashCodeV = -hashCodeV;
		}
		// 0 代表前面补充0
		// 4 代表长度为4
		// d 代表参数为正数型
		return machineId + String.format("%012d", hashCodeV);
	}

	public static String getSign(SortedMap<String, String> parameters, String key) {
		return requestSign(parameters, key);
	}

	private static String requestSign(SortedMap<String, String> parameters, String key) {
		StringBuffer sb = new StringBuffer();
		StringBuffer sbkey = new StringBuffer();
		String characterEncoding = "UTF-8";
		// 所有参与传参的参数按照accsii排序（升序）
		Set<Map.Entry<String, String>> es = parameters.entrySet();
		Iterator<Entry<String, String>> it = es.iterator();
		while (it.hasNext()) {
			Map.Entry<String, String> entry = it.next();
			String k = entry.getKey();
			String v = entry.getValue();
			// 空值不传递，不参与签名组串
			if (org.apache.commons.lang3.StringUtils.isNotBlank(v)) {
				sb.append(k + "=" + v + "&");
				sbkey.append(k + "=" + v + "&");
			}
		}
		LOGGER.debug("字符串 {}", sb.toString());
		sbkey = sbkey.append("key=" + key);
		LOGGER.info("MD5前的字符串：{}", sbkey.toString());
		// MD5加密,结果转换为大写字符
		String sign = MD5Util.getMD5(sbkey.toString(), characterEncoding).toUpperCase();
		LOGGER.info("MD5后的字符串： {}", sign);
		return sign;
	}

	// public static void main(String[] args) {
	// SortedMap<String, String> parameters = new TreeMap<String, String>();
	// // String mfrchant_id="fffff";
	// String merchant_id = "190010002";
	// String business_type = "1005";
	// String out_trade_no = "1400000001";
	// String key = "3A4BC4A4000CF1B5FFA9E351E6C1539E";
	// // parameters.put("mfrchant_id", mfrchant_id);
	// parameters.put("merchant_id", merchant_id);
	// parameters.put("business_type", business_type);
	// parameters.put("out_trade_no", out_trade_no);
	// String mySign = requestSign(parameters, key);
	// System.out.println(mySign);
	// }

}
